﻿/*
 Copyright (c) 2009 Alvin Cho (alvincho@risklib.com)
 Copyright (c) 2009 RiskLib.com
 
 This file is part of RiskLib.NET Project. See http://www.risklib.net for more information.
 
 RiskLib.NET is an open source project. Using of RiskLib.NET is free of charge.
 It is distributed under GNU General Public License version 2 (GPLv2).
 GPLv2 can be found at http://www.risklib.net/risklib/license.
 
 This program is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE.  See the license for more details.
*/
using System;
using System.Collections.Generic;
using System.Text;

namespace RiskLib
{
    public class FundamentalDataList : Dictionary<FieldNameEnum, IFieldData>
    {
        public static  FundamentalDataList operator+(FundamentalDataList list1, FundamentalDataList list2)
        {
            throw new NotImplementedException("FundamentalDataList operator+ NotImplemented");
        }
        public static FundamentalDataList operator /(FundamentalDataList list1, int i)
        {
            throw new NotImplementedException("FundamentalDataList operator+ NotImplemented");
        }
        public List<FieldNameEnum> CommonFields(FundamentalDataList theOtherList)
        {
            List<FieldNameEnum> list = new List<FieldNameEnum>();
            foreach (FieldNameEnum field in this.Keys)
            {
                if (theOtherList.ContainsKey(field))
                    list.Add(field);
            }
            return list;
        }
    }

    public class ProductFieldDataList : Dictionary<IProductCode, FundamentalDataList> { }

    public class Field
    {
        public static IFieldData CreateFieldDataInstance(FieldNameEnum field)
        {
            IFieldData result;
            switch (field)
            {
                //case FieldNameEnum.ExerciseType:
                //    result = new FieldExerciseType();
                //    break;
                default:
                    result = new FieldNumeric();
                    break;
            }
            return result;
        }
    }
    public interface IFieldData
    {
        object Data { get; set; }
        bool IsCollection { get; }
        bool IsEnumeration { get; }
        bool IsNumeric { get; }
        Type DataType { get; }
        IFieldData Add(IFieldData fd);
    }
    public class FieldInteger : GenericFieldData<int>
    {

        public override bool IsEnumeration
        {
            get { throw new NotImplementedException(); }
        }

        public override bool IsNumeric
        {
            get { throw new NotImplementedException(); }
        }

        public override Type DataType
        {
            get { throw new NotImplementedException(); }
        }
    }
    public class FieldNumeric:GenericFieldData<double>
    {
        public static explicit operator FieldNumeric(double v)
        {
            FieldNumeric result = new FieldNumeric();
            result.data = v;
            return result;
        }

        public override bool IsEnumeration
        {
            get { return false; }
        }

        public override bool IsNumeric
        {
            get { return true;}
        }

        public override Type DataType
        {
            get { throw new NotImplementedException(); }
        }
    }

    public class FieldString : GenericFieldData<string>
    {
        public override bool IsEnumeration
        {
            get { throw new NotImplementedException(); }
        }

        public override bool IsNumeric
        {
            get { throw new NotImplementedException(); }
        }

        public override Type DataType
        {
            get { throw new NotImplementedException(); }
        }
    }

    public class FieldDateTime : GenericFieldData<DateTime>
    {
        public override bool IsEnumeration
        {
            get { throw new NotImplementedException(); }
        }

        public override bool IsNumeric
        {
            get { throw new NotImplementedException(); }
        }

        public override Type DataType
        {
            get { throw new NotImplementedException(); }
        }
    }

    public class FieldEnumeration<T> : GenericFieldData<T>
    {
        public override bool IsEnumeration
        {
            get { return true; }
        }

        public override bool IsNumeric
        {
            get { throw new NotImplementedException(); }
        }

        public override Type DataType
        {
            get { return data.GetType(); }
        }
    }

    //public class FieldExerciseType : FieldEnumeration<ExerciseType>
    //{
    //    public static explicit operator FieldExerciseType(ExerciseType type)
    //    {
    //        FieldExerciseType result=new FieldExerciseType();
    //        result.data = type;
    //        return result;
    //    }
    //}
    public abstract class GenericFieldData<T> : IFieldData
    {
        protected T data;

        #region IFieldData 成員

        public object Data
        {
            get { return data; }
            set { data = (T)value; }
        }

        public bool IsCollection
        {
            get { return false; }
        }

        public abstract bool IsEnumeration
        {
            get;
        }

        public abstract bool IsNumeric
        {
            get;
        }

        public abstract Type DataType
        {
            get;
        }

        #endregion

        public override string ToString()
        {
            return data.ToString();
        }
        #region IFieldData 成員


        public IFieldData Add(IFieldData fd)
        {
            FieldNumeric result = new FieldNumeric();
            if (IsNumeric)
                result.Data =(double)Data+ (double)fd.Data;
            return result;
        }

        #endregion
    }
    public abstract class GenericFieldList<T> : IFieldData
    {
        protected List<T> data;
        public object Data
        {
            get { return data; }
            set { data = (List<T>)value; }
        }

        #region IFieldData 成員


        public bool IsCollection
        {
            get { throw new NotImplementedException(); }
        }

        public bool IsEnumeration
        {
            get { throw new NotImplementedException(); }
        }

        public bool IsNumeric
        {
            get { throw new NotImplementedException(); }
        }

        public Type DataType
        {
            get { throw new NotImplementedException(); }
        }

        public IFieldData Add(IFieldData fd)
        {
            throw new NotImplementedException();
        }

        #endregion
    }
}
